﻿#include "stdafx.h"
#include "AstBinary.h"
#include "SiContext.h"
#include "CodeGenerate/BinaryGen.h"
#include "CodeGenerate/IntegerBinaryGen.h"
#include "CodeGenerate/ClassBinaryGen.h"
#include "CodeGenerate/StringLiteGen.h"
#include "utility.h"
#include <exception>

using namespace llvm;

AstBinary::AstBinary(int o, AstNode * left, AstNode * right) : op(o) {
	this->left = left;
	this->right = right;
	name.push_back((char)o);
}

CodeGen* AstBinary::makeGen(SiContext * parent)
{
	auto l = left->makeGen(parent);
	auto r = right->makeGen(parent);

	auto lt = l->type;
	auto rt = l->type;

	if (lt->isClass() || rt->isClass())
		return new ClassBinaryGen(op, l, r);

	if (lt->isInteger() && rt->isInteger()) {
		return new IntegerBinaryGen(op, l, r);
	}
	else if (lt->isNumber() && rt->isNumber()) {
		return new BinaryGen(op, l, r);
	}
	else if (lt->isString() && rt->isString()) {
		auto lg=dynamic_cast<StringLiteGen*>(l);
		auto rg = dynamic_cast<StringLiteGen*>(r);
		lg->str += rg->str;
		delete rg;
		return lg;
	}

	throw std::runtime_error("Binary opertor with unknown type");
}

void AstBinary::draw(std::ostream & os)
{
	dotPointTo(os, left);
	dotPointTo(os, right);

	dotLable(os, operator_to_str(op));
}
